package com.tangding;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
import org.springframework.context.annotation.Bean;

import com.tangding.common.logx.LogHelp;
import com.tangding.config.Config;
import com.tangding.hprose.api.HproseApiHelper;
import com.tangding.hprose.api.server.HproseApiServer4GameServer;
import com.tangding.hprose.config.HproseConfig;
import com.tangding.net.tcp.GameNettyServer;

import hprose.common.HproseFilter;
import hprose.server.HproseTcpServer;

/**
 * @description tcp 服务启动
 *
 * @author Ranger
 * @version 2017年11月21日_下午12:21:39
 *
 */
@SpringBootApplication(exclude = {MongoAutoConfiguration.class, RabbitAutoConfiguration.class})
public class TCPSocketLauncher implements CommandLineRunner{
	
	public static void main(String[] args) {
		try{
			SpringApplication.run(TCPSocketLauncher.class, args);
		}catch (Exception e) {
			LogHelp.doLogException(e);
		}
	}

	@Override
	public void run(String... args) throws Exception {
		LogHelp.doLogApp("service start succ...");
		Thread.currentThread().join();
	}
	
	@Bean
	public GameNettyServer tcpSocketServerStarter(GameNettyServer server) {
		server.start(Config.nettyServerHost, Config.nettyServerPort);
		return server;
	}
	
	@Bean
	public HproseTcpServer hproseTcpServer(@Qualifier("hproseConfig") HproseConfig config) throws URISyntaxException, IOException {
		HproseTcpServer server = new HproseTcpServer(config.getHost());
		List<HproseFilter> filters = config.getFilters();
		if (filters != null && filters.size() > 0) {
			for (HproseFilter filter : filters) {
				server.addFilter(filter);
			}
		}
		
		Map<String, Class<?>> apiList = config.getApiMap();
		if (apiList != null && apiList.size() > 0) {
			for (Map.Entry<String, Class<?>> entry : apiList.entrySet()) {
				String key = entry.getKey();
				Class<?> value = entry.getValue();
				server.add(key, value);
			}
		}
		
//        server.setDebugEnabled(true);
        server.start();
        return server;
	}
	
	@Bean("hproseConfig")
	public HproseConfig hproseConfig(@Autowired(required = false) List<HproseFilter> filters, HproseApiHelper helper) {
		HproseConfig config = new HproseConfig();
		config.setHost(Config.hproseAsServerHost);
		Map<String, Class<?>> apiMap = helper.findStaticMethod();
		config.appendApiMap(apiMap);
		if (filters != null && filters.size() > 0) {
			config.setFilters(filters);
		}
		return config;
	}
	
	
	@Bean
	public HproseTcpServer hproseTcp4GameServer(@Qualifier("hprose4GameServerConfig") HproseConfig config) throws URISyntaxException, IOException {
		HproseTcpServer server = new HproseTcpServer(config.getHost());
		List<HproseFilter> filters = config.getFilters();
		if (filters != null && filters.size() > 0) {
			for (HproseFilter filter : filters) {
				server.addFilter(filter);
			}
		}
		
		Map<String, Class<?>> apiList = config.getApiMap();
		if (apiList != null && apiList.size() > 0) {
			for (Map.Entry<String, Class<?>> entry : apiList.entrySet()) {
				String key = entry.getKey();
				Class<?> value = entry.getValue();
				server.add(key, value);
			}
		}
		
//        server.setDebugEnabled(true);
        server.start();
        return server;
	}
	
	@Bean("hprose4GameServerConfig")
	public HproseConfig hprose4GameServerConfig(@Autowired(required = false) List<HproseFilter> filters) {
		HproseConfig config = new HproseConfig();
		config.setHost(Config.hproseAsServer4GameServerHost);
		Map<String, Class<?>> apiMap = HproseApiHelper.findStaticMethod(HproseApiServer4GameServer.class);
		config.appendApiMap(apiMap);
		if (filters != null && filters.size() > 0) {
			config.setFilters(filters);
		}
		return config;
	}
}